//
//  SEGOpenDoorViewModel.m
//  Commom
//
//  Created by Clavis on 2020/6/3.
//

#import "SEGOpenDoorViewModel.h"
#import <SEGModel/SEGNewDoorManager.h>
#import <SEGModel/SEGUhomeNetworkDoorManager.h>
#import <SEGModel/SEGQinlinBluetoothDoorManager.h>
#import <SEGModel/SEGUhomeBluetoothDoorManager.h>
#import <SEGModel/SEGIbeaconDoorManager.h>
#import <SEGModel/SEGDHBLEDoorManager.h>
#import <SEGModel/SEGiKeyManager.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <SEGPlatform/SEGAnalyseBehaviorManager.h>

#define SEGOpenDoorHistoryLocalKey @"subHis" //本地保存开门记录的key
#define SEGDoorError(A,B) [NSError errorWithDomain:NSURLErrorDomain code:A userInfo:@{NSLocalizedDescriptionKey:B}]
#define SEGDoorMarco_OpenBlueDoorFailTitle @"很抱歉，手机开门出现问题，建议您："
#define SEGDoorMarco_OpenBlueDoorFailDetail @"1，尝试靠近点；\n2，重新安装程序，确保应用的蓝牙使用权限是允许的；\n3，可以用其他的手机试一下，确保门和手机都没有问题；\n4，如果周围邻居都无法开门则可能是门禁系统出了问题，请联系管理处反馈，方便您下次使用。"

@interface SEGOpenDoorViewModel ()

@property (nonatomic, strong) RACSignal *openDoorSignal;
@property (nonatomic, strong) RACSignal *openRollingGateDoorSignal;
@property (nonatomic, strong) SEGNewMyDoorListModel *doorModel;
/// 卷闸门开门操作
@property (nonatomic, assign) NSInteger actionType;//用于卷闸门开门

// 亲邻科技蓝牙门管理对象
@property (nonatomic, strong) SEGQinlinBluetoothDoorManager *qinlinBluetoothDoorManager;
// 优家园蓝牙门管理对象
@property (nonatomic, strong) SEGUhomeBluetoothDoorManager *uhomeBluetoothDoorManager;
// 优家园联网门管理对象
@property (nonatomic, strong) SEGUhomeNetworkDoorManager *uhomeNetworkDoorManager;
// ibeacon门管理对象
@property (nonatomic, strong) SEGIbeaconDoorManager *ibeaconDoorManager;
// 大豪蓝牙门管理对象
@property (nonatomic, strong) SEGDHBLEDoorManager *dhBLEDoorManager;
// 智锁蓝牙门管理对象
@property (nonatomic, strong) SEGiKeyManager *iKeyManager;
// 用于判断蓝牙状态
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;

@end

@implementation SEGOpenDoorViewModel

singleton_m(SEGOpenDoorViewModel);

/// 开门信号量
/// @param doorModel doorModel
- (RACSignal *)openDoorSignal:(SEGNewMyDoorListModel *)doorModel {
    self.doorModel = doorModel;
    return self.openDoorSignal;
}

- (RACSignal *)openDoorSignal {
    if (!_openDoorSignal) {
        @weakify(self);
        _openDoorSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            @strongify(self);
            
            // doorModel不存在 异常处理
            SEGNewMyDoorListModel *doorModel = self.doorModel;
            if (!doorModel) {
                [subscriber sendError:SEGDoorError(SEGOpenDoorErrorType_Unsupport, kOpenDoorMessage_Unsupport)];
                return nil;
            }
            
            SEGDoorDeviceType deviceType = [doorModel.deviceType integerValue];
            SEGDoorType doorType = [doorModel.doorType integerValue];
            
            // 4.9.6 二维码门禁改成走接口生成 & 不判断设备类型，所有二维码都支持
            if (doorType == SEGDoorDeviceType_QRCode) { //二维码门禁
                [self openQRCodeDoorWithSubscriber:subscriber];
                return nil;
            }
            
            // 5.0.0 新增卷闸门（不判断设备类型）
            if (doorType == SEGDoorDeviceType_RollingGate) {
                [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_ShowRollingGate), @"")];
                [subscriber sendCompleted];
                return nil;
            }
            
            // 设置开门成功后(蓝牙和网络门禁)积分行为请求成功要提示
            [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:SEGIbeaconShowTipsUserDefaults];
            
            switch (deviceType) {
                case SEGDoorDeviceType_Uhome:
                {
                    switch (doorType) {
                        case SEGDoorDeviceType_Common: // 普通联网门
                        {
                            [self openNetworkDoorWithSubscriber:subscriber];
                            break;
                        }
                        case SEGDoorDeviceType_Bluetooth: // 蓝牙们
                        {
                            [self openBluetoothDoor:self.uhomeBluetoothDoorManager subscriber:subscriber];
                            break;
                        }
                        case SEGDoorDeviceType_QRCode: // 二维码门禁
                        {
                            [self openQRCodeDoorWithSubscriber:subscriber];
                            break;
                        }
                        default:
                            // 不支持的门禁类型
                            [subscriber sendError:SEGDoorError(SEGOpenDoorErrorType_Unsupport, kOpenDoorMessage_Unsupport)];
                            break;
                    }
                    break;
                }

                case SEGDoorDeviceType_QinLin://亲邻科技 蓝牙
                {
                    [self openBluetoothDoor:self.qinlinBluetoothDoorManager subscriber:subscriber];
                    break;
                }
                case SEGDoorDeviceType_Ibeacon://新蓝牙ibeacon
                {
                    // ibeacon成功后积分行为不提示
                    [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:SEGIbeaconShowTipsUserDefaults];
                    [self openBluetoothDoor:self.ibeaconDoorManager subscriber:subscriber];
                    break;
                }
                case SEGDoorDeviceType_DHBLE://大豪蓝牙门禁
                {
                    [self openBluetoothDoor:self.dhBLEDoorManager subscriber:subscriber];
                    break;
                }
                case SEGDoorDeviceType_IKey://智锁蓝牙门禁
                {
                    [self openBluetoothDoor:self.iKeyManager subscriber:subscriber];
                    break;
                }
                case SEGDoorDeviceType_HaiKang: //海康二维码门禁
                {
                    [self openQRCodeDoorWithSubscriber:subscriber];
                    break;
                }
                default:
                    /*
                     1.【5.2.0】 新增慧锐通网络门：doorType:1 deviceType:11
                     2. 以上门禁类型都匹配不上的门禁 & 门禁类型是网络门 => 请求网络门新接口
                     3. 由于线上数据亲邻科技&ibeacon门禁的配置doortype可能是1，所以该逻辑不能提前到deviceType之前判断
                     */
                    if (doorType == SEGDoorDeviceType_Common) {
                        [self openNewNetworkDoorWithSubscriber:subscriber];
                        return nil;
                    }
                    
                    // 不支持的门禁类型
                    [subscriber sendError:SEGDoorError(SEGOpenDoorErrorType_Unsupport, kOpenDoorMessage_Unsupport)];
                    break;
            }
            
            return nil;
        }];
    }
    return _openDoorSignal;
}


/// 开卷闸门
/// @param doorModel doorModel
- (RACSignal *)openRollingGateDoorSignal:(SEGNewMyDoorListModel *)doorModel actionType:(NSInteger)actionType {
    self.doorModel = doorModel;
    self.actionType = actionType;
    return self.openRollingGateDoorSignal;
}

- (RACSignal *)openRollingGateDoorSignal {
    if (!_openRollingGateDoorSignal) {
        @weakify(self);
        _openRollingGateDoorSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            @strongify(self);
        
            // 5.0.0 新增卷闸门逻辑
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/door-restapi/v1/userapp/opendoor/submit.json",nil];
            NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
            NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
            NSDictionary *param = @{
                @"userId": kAccountUserID?:@"",
                @"custId": kAccountCustId?:@"",
                @"doorId": self.doorModel.doorId ?:@"",
                @"communityId": kAccountCommunityID ?: @"",
                @"doorIdStr": self.doorModel.doorIdStr,
                @"appVersion": app_Version ?: @"",
                @"appType": @"2",
                @"actionType": @(self.actionType).stringValue
            };
            
            [SEGHTTPBusinessManager seg_requestJSONWithMethod:POST URLString:urlString parameters:param finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
                if (isSuccessed) {
                    [subscriber sendNext:errorMessage];
                    [subscriber sendCompleted];
                }
                NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:[codeType integerValue] userInfo:@{NSLocalizedDescriptionKey:errorMessage}];
                [subscriber sendError:error];
            }];
            return nil;
        }];
    }
    return _openRollingGateDoorSignal;
}


/// 打开蓝牙门禁
/// @param doorAPI doorAPI
/// @param subscriber subscriber
- (void)openBluetoothDoor:(SEGOpenDoorBaseAPI *)doorAPI subscriber:(id<RACSubscriber>)subscriber {
    [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Begin), kOpenDoorMessage_Opening)];
    
    // 检测蓝牙状态
    self.peripheralManager = nil;
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@(NO)}];
    @weakify(self);
    [[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{
        @strongify(self);
        // 蓝牙初始化成功
        if (self.peripheralManager.state == CBPeripheralManagerStatePoweredOn) {
            doorAPI.doorModel = self.doorModel;
            doorAPI.peripheralManager = self.peripheralManager;
            self.peripheralManager.delegate = doorAPI;
            if (!doorAPI.delegateSubject) {
                doorAPI.delegateSubject = [RACSubject subject];
            }
            [doorAPI.delegateSubject subscribeNext:^(id  _Nullable x) {
                [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Success), nil)];
                [subscriber sendCompleted];
                //保存开门记录
                [self seg_saveOpenDoorRecordWithIsSuccess:YES doorModel:self.doorModel];
            } error:^(NSError * _Nullable error) {
                NSError *tempError = [NSError errorWithDomain:NSNetServicesErrorDomain code:SEGOpenDoorErrorType_OpenBluetoothDoorFail userInfo:@{NSLocalizedDescriptionKey:SEGDoorMarco_OpenBlueDoorFailDetail, SEGOpenDoorErrorTipTitleKey:SEGDoorMarco_OpenBlueDoorFailTitle}];
                [subscriber sendError:tempError];
                //保存开门记录
                [self seg_saveOpenDoorRecordWithIsSuccess:NO doorModel:self.doorModel];
            }];
            [doorAPI openDoor];
            return;
        }
        
        // 蓝牙未授权&未打开等错误处理
        NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:SEGOpenDoorErrorType_NoBluetoothAuthority userInfo:@{NSLocalizedDescriptionKey:@"", SEGOpenDoorFailBluetoothStateKey:@(self.peripheralManager.state)}];
        [subscriber sendError:error];
    }];
}

/// 打开二维码门禁
/// @param subscriber subscriber
- (void)openQRCodeDoorWithSubscriber:(id<RACSubscriber>)subscriber {
    [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Begin), kOpenDoorMessage_Opening)]; //开始请求

    // 4.9.6逻辑 二维码门禁全部请求接口 不是要本地规则生成(包括sany海康门禁)
    NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/door-restapi/v1/userapp/generateQRCodeForDoor",nil];
    NSDictionary *param = @{@"deviceType" : @([self.doorModel.deviceType integerValue]),
                            @"communityId" : kAccountCommunityID ?: @"",
                            @"tel" : kAccountMobile ?: @"",
                            @"deviceId" : self.doorModel.deviceid ?: @""
                            };
    [SEGHTTPBusinessManager seg_requestWithMethod:GET URLString:urlString parameters:param finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
        // codeType 0：成功；-1：失败；2：无门禁权限
        if ([codeType integerValue] == 2) {
            [subscriber sendError:SEGDoorError(SEGOpenDoorErrorType_NoQRDoorAuthority, errorMessage)];
            return;
        }
        // 传出二维码
        NSString *QRCodeString = result[@"data"] ?: @"";
        [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_ShowQRCode), QRCodeString)];
        [subscriber sendCompleted];
    }];
}

/// 打开网络门禁
/// @param subscriber subscriber
- (void)openNetworkDoorWithSubscriber:(id<RACSubscriber>)subscriber {
    [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Begin), kOpenDoorMessage_Opening)]; //开始请求
    
    [self.uhomeNetworkDoorManager.delegateSubject subscribeNext:^(id  _Nullable x) {
        [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Success), nil)];
        [subscriber sendCompleted];
    } error:^(NSError * _Nullable error) {
        [subscriber sendError:error];
    }];
    self.uhomeNetworkDoorManager.doorModel = self.doorModel;
    [self.uhomeNetworkDoorManager openDoor];
}


/// 新：打开网络门禁
/// @param subscriber subscriber
- (void)openNewNetworkDoorWithSubscriber:(id<RACSubscriber>)subscriber {
    [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Begin), kOpenDoorMessage_Opening)]; //开始请求
    
    [self.uhomeNetworkDoorManager.delegateSubject subscribeNext:^(id  _Nullable x) {
        [subscriber sendNext:RACTuplePack(@(SEGOpenDoorStatus_Success), nil)];
        [subscriber sendCompleted];
    } error:^(NSError * _Nullable error) {
        [subscriber sendError:error];
    }];
    self.uhomeNetworkDoorManager.doorModel = self.doorModel;
    [self.uhomeNetworkDoorManager openNewNetworkDoor]; //新接口
}

#pragma mark - 蓝牙门开门完成的操作
- (void)seg_saveOpenDoorRecordWithIsSuccess:(BOOL)isSuccess doorModel:(SEGNewMyDoorListModel *)doorModel {
    NSMutableDictionary* hisDic = [NSMutableDictionary dictionary];
    hisDic[@"communityId"] = ValueToString(kAccountCommunityID);
    hisDic[@"userId"] = ValueToString(kAccountUserID);
    hisDic[@"custId"] = ValueToString([SEGProfileManager sharedManager].profile.custId);
    hisDic[@"doorId"] = doorModel.doorId;
    //获取系统当前的时间戳
    NSTimeInterval a= [[NSDate date] timeIntervalSince1970];
    NSString *timeString = [NSString stringWithFormat:@"%.0f", a];//转为字符型
    hisDic[@"openTime"] = timeString;
    //开门状态
    NSString *openStatusString = isSuccess ? @"1" : @"2";//开门状态：1开门成功 2开门失败
    hisDic[@"openStatus"] = openStatusString;
    hisDic[@"appVersion"] = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; //APP版本
    
    //保存开门历史数组到本地
    NSMutableArray *hisArray = [NSMutableArray array];
    NSArray *localHistoryArray = [[NSUserDefaults standardUserDefaults] arrayForKey:SEGOpenDoorHistoryLocalKey];
    if (localHistoryArray) {
        hisArray = [NSMutableArray arrayWithArray:localHistoryArray];
    }
    [hisArray addObject:hisDic];
    [[NSUserDefaults standardUserDefaults] setObject:hisArray forKey:SEGOpenDoorHistoryLocalKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

#pragma Getter & Setter

#pragma mark - Getter
- (SEGQinlinBluetoothDoorManager *)qinlinBluetoothDoorManager {
    if (!_qinlinBluetoothDoorManager) {
        _qinlinBluetoothDoorManager = [[SEGQinlinBluetoothDoorManager alloc] init];
        _qinlinBluetoothDoorManager.delegateSubject = [RACSubject subject];
    }
    return _qinlinBluetoothDoorManager;
}
- (SEGUhomeBluetoothDoorManager *)uhomeBluetoothDoorManager {
    if (!_uhomeBluetoothDoorManager) {
        _uhomeBluetoothDoorManager = [[SEGUhomeBluetoothDoorManager alloc] init];
        _uhomeBluetoothDoorManager.delegateSubject = [RACSubject subject];
    }
    return _uhomeBluetoothDoorManager;
}
- (SEGUhomeNetworkDoorManager *)uhomeNetworkDoorManager {
    if (!_uhomeNetworkDoorManager) {
        _uhomeNetworkDoorManager = [[SEGUhomeNetworkDoorManager alloc] init];
        _uhomeNetworkDoorManager.delegateSubject = [RACSubject subject];
    }
    return _uhomeNetworkDoorManager;
}

- (SEGIbeaconDoorManager *)ibeaconDoorManager {
    if (!_ibeaconDoorManager) {
        _ibeaconDoorManager = [[SEGIbeaconDoorManager alloc] init];
        _ibeaconDoorManager.delegateSubject = [RACSubject subject];
    }
    return _ibeaconDoorManager;
}
- (SEGDHBLEDoorManager *)dhBLEDoorManager {
    if (!_dhBLEDoorManager) {
        _dhBLEDoorManager = [[SEGDHBLEDoorManager alloc] init];
        _dhBLEDoorManager.delegateSubject = [RACSubject subject];
    }
    return _dhBLEDoorManager;
}
- (SEGiKeyManager *)iKeyManager {
    if (!_iKeyManager) {
        _iKeyManager = [SEGiKeyManager sharedIkey];
        _iKeyManager.delegateSubject = [RACSubject subject];
    }
    return _iKeyManager;
}

@end
